
import numpy as np
import os
import matplotlib.pyplot as plt
from PIL import Image
import subprocess
import sys

FNULL = open(os.devnull,'w')

base_address = 0xfd400000;
adder_base_adress = 0xfda00000;
fifo_write_base_adress  = 0xfdb00000;
fifo_read_base_adress   = 0xfdd00000;
gpio_1_read_based_adress = 0xfde00000;
gpio_2_read_based_adress = 0xfd070000;

fifo_P_read_base_address = 0xfdc00000;
fifo_PIX_BUFF_read_base_address = 0xfd080000;
fifo_CTX0_BUFF_read_base_address = 0xfdd00000;
fifo_BAC_BUFF_read_base_address  = 0xfd090000;

def read_FPGA_reg_val(base_address,offset):
    s = subprocess.check_output(["devmem2",str(base_address+offset),"h"],stderr = subprocess.STDOUT)
    s = s.split(" ")
    s = s[len(s)-1]
    s = s.replace("\n","")
    return int(s,16)

def read_FPGA_reg_val32(base_address,offset):
    s = subprocess.check_output(["devmem2",str(base_address+offset),"w"],stderr = subprocess.STDOUT)
    s = s.split(" ")
    s = s[len(s)-1]
    s = s.replace("\n","")
    return int(s,16)

def write_FPGA_reg_val(base_address,offset,val):
    return subprocess.call(["devmem2",str(base_address+offset),"w",str(hex(val))],stdout = FNULL,stderr = subprocess.STDOUT)



def convert_4x8_to_32(val3,val2,val1,val0):
    return val3*256*256*256+val2*256*256+val1*256+val0
def convert_32_to_4x8(val):
    val0 = val&255;
    val1 = (val >> 8)&255;
    val2 = (val >> 16)&255;
    val3 = (val >> 24)&255;
    return [val3,val2,val1,val0]

def write_FPGA_CREG(val):
   return write_FPGA_reg_val(fifo_write_base_adress,4,val)

def read_FPGA_CREG():
   return read_FPGA_reg_val(gpio_1_read_based_adress,0)

def read_FPGA_RX_FIFO_CNT():
   return read_FPGA_reg_val(gpio_1_read_based_adress,8)
def read_FPGA_IMG_FSM_ID():
   return read_FPGA_reg_val(gpio_2_read_based_adress,0)

def read_FPGA_P_FIFO():
   return read_FPGA_reg_val(fifo_P_read_base_address,0)

def read_FPGA_PIX_BUFF_FIFO():
   return read_FPGA_reg_val32(fifo_PIX_BUFF_read_base_address,0)

def read_FPGA_CTX_BUFF_FIFO():
   return read_FPGA_reg_val(fifo_CTX0_BUFF_read_base_address,0)

def read_FPGA_BAC_BUFF_FIFO():
   return read_FPGA_reg_val32(fifo_BAC_BUFF_read_base_address,0)
def read_FPGA_BAC_FIFO_CNT():
   return read_FPGA_reg_val32(fifo_BAC_BUFF_read_base_address,8)

def progress(count, total, status=''):
    bar_len = 60
    filled_len = int(round(bar_len * count / float(total)))

    percents = round(100.0 * count / float(total), 1)
    bar = '=' * filled_len + '-' * (bar_len - filled_len)

    sys.stdout.write('[%s] %s%s ...%s\r' % (bar, percents, '%', status))
    sys.stdout.flush() 

img = Image.open('b6l.bmp')
img = np.array(img)
img_tmp = img*0;
img32 = np.zeros(512*512/4)

for i in range(512):
    img_tmp[i] = img[511-i]
img = img_tmp
print(img)
img = img.flatten()
img = np.append(0,img)


img32 = np.zeros(512*512/4)

for i in range((65535)):
    img32[i] = convert_4x8_to_32(img[((i+1)*4-3)],img[((i+1)*4-2)],img[((i+1)*4-1)],img[((i+1)*4-0)])


step = 0x04;

i = 0x00;

print('Uploading image')
for j in range(65535):
    write_FPGA_reg_val(fifo_write_base_adress,0,img32[j])
    progress(j,65535)


s = read_FPGA_reg_val(fifo_write_base_adress,step)
print('Number of bytes written := ',s)
write_FPGA_CREG(64)
s = read_FPGA_reg_val(fifo_write_base_adress,step)
print('Number of bytes written after CREG assert := ',s)

s = read_FPGA_CREG()
print('Written vale of CREG := ',s)

s = read_FPGA_RX_FIFO_CNT()
print('RX FIFO CNT := ',s)

s = read_FPGA_IMG_FSM_ID()
print('IMG FSM ID := ',s)


while(s > 0):
   s = read_FPGA_RX_FIFO_CNT()

s = read_FPGA_reg_val(fifo_read_base_adress,step)
print('Bytes left at read FIFO := ',s)

s = read_FPGA_BAC_FIFO_CNT()
print('Bytes left at BAC fifo := ',s)
for j in range(s):
     s = convert_32_to_4x8(read_FPGA_BAC_BUFF_FIFO())
     print("BAC_VAL =  ",s[0])
     print("BAC_VAL =  ",s[1])
     print("BAC_VAL =  ",s[2])
     print("BAC_VAL =  ",s[3])
